#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::istringstream;
using std::string;
using std::vector;
using std::set;
using std::map;

class TextQuery
{
public:
    TextQuery(size_t capacity)
    {
        _lines.reserve(capacity);
    }


	//读取文件，处理内容，将需要的信息
	void readFile(const string & filename)
    {
        ifstream ifs(filename);

        if(!ifs)
        {
            cerr << "ifstream open file failed" << endl;
            return;
        }

        string line;
        int lineNumber = 1;
        while(std::getline(ifs,line))
        {
            _lines.push_back(line);

            //先处理一行
            dealLine(line);

            istringstream iss(line);
            string word;
            while(iss >> word)
            {
                ++_dict[word];

                _wordNumbers[word].insert(lineNumber);
            }
            
            ++lineNumber;
        }

        ifs.close();
    }

    void dealLine(string & line)
    {
        //不应该直接舍弃与符号连在一起的单词
        //也不应该直接将Shenzhen-HK处理成ShenzhenHK
        //处理一行内容时，使用空格符替代“非法字符”
        for(auto & ch : line)
        {
            if(!isalpha(ch))
            {
                ch = ' ';
            }else if(isupper(ch))
            {
                ch = tolower(ch);
            }
        }
    }


    //查找单词
	void query(const string & word)
    {
        cout << "--------------" << endl;
        int count = _dict[word];
        cout << word << " occurs " << count
            << (count > 1 ? " times." : " time.")
            << endl;

        set<int> ls = _wordNumbers[word];
        for(auto & num : ls)
        {
            cout << "(line " << num << ") "
                << _lines[num - 1] << endl;
        }
    }


private:
	//把每一行的原始信息存储下来
	vector<string> _lines;
    //单词和行号
	map<string, set<int> > _wordNumbers;
    //单词和词频
	map<string, int> _dict;
};

int main(int argc, char *argv[])
{
	TextQuery tq(107);
	tq.readFile("china_daily.txt");
	tq.query("chinese");
	return 0;
}
